<script setup lang="ts">
import { PickTablePage } from '@pickmall/ui-v3-components'
import { Message } from '@arco-design/web-vue'
import type { FormInstance } from '@arco-design/web-vue/es/form'
import {
  addRole,
  deleteRole,
  editRole,
  getAllPermissionList,
  getRoleList,
  saveRoleMenu,
  selectRoleMenu,
} from '@/api/shops'
import useCurrentInstance from '@/hooks/useCurrentInstance'
import type { ColumnsDataRule, MethodsRule } from '@/types/global'
import { REQUIRED, VARCHAR20 } from '@/utils/validator'

const tablePageRef = ref<any>()
const title = ref<string>('')
const selectList = ref([]) // 接收子组件传过来的值
const formRef = ref<FormInstance>()
const ids = ref<string>('') // 多选行id
const permModalVisible = ref(false) // 菜单权限modal
const selectIsSuperModel = ref(false) // 保存权限弹出选择权限
const permData = ref([]) // 菜单权限数据
const saveRoleWay = ref<Array<any>>([]) // 用户保存用户点击的菜单
const editRolePermId = ref('') // 编辑权限id
const rolePermsWay = ref([]) // 查询角色权限集合
const treeRef = ref()
interface formInterface {
  enableAddModal: boolean
  formLoading: boolean
  fid: string | number
  form: {
    name: string
    description: string
    [key: string]: any
  }
  [key: string]: any
}
// 获取modal
const modal = useCurrentInstance().globalProperties?.$modal
const columnsTable: ColumnsDataRule[] = [
  {
    title: '角色名称',
    dataIndex: 'name',
    width: 200,
  },
  {
    title: '备注',
    dataIndex: 'description',
    width: 200,
  },
  {
    title: '创建时间',
    dataIndex: 'createTime',
    width: 300,
  },
  {
    title: '更新时间',
    dataIndex: 'updateTime',
    width: 300,
  },
  {
    title: '最后操作人',
    dataIndex: 'createBy',
    width: 300,
  },
]

const sortMethods: MethodsRule = {
  title: '操作',
  width: 300,
  fixed: 'right',
  methods: [
    // {
    //   title: '菜单权限',
    //   callback: 'editPerm',
    //   type:'text'
    // },
    {
      title: '编辑',
      callback: 'editor',
      type: 'text',
      status: 'warning',
    },
    {
      title: '删除',
      callback: 'delete',
      type: 'text',
      status: 'danger',
    },
  ],
}
function changeIsSuper(val: any, item: any) {
  if (item.level === 0) {
    // 选中一级之后为子集全选相同全选
    const current: any = permData.value.find(
      (per: any) => item.menuId === per.id,
    )
    const currentChildren = current.children
    if (currentChildren.length) {
      // 遍历出所有子集
      const ids = currentChildren.map((per: any) => per.id)
      saveRoleWay.value.map((per: any) => {
        if (ids.includes(per.menuId)) {
          per.isSuper = val
        }
      })
      Message.success(
        `已将${item.title}下所有子集权限设置为${val ? '操作' : '查看'}权限`,
      )
    }
  }
}
// 数据集
const roleData = reactive<formInterface>({
  enableAddModal: false,
  formLoading: false,
  fid: '', // 当前form的ids
  form: {
    name: '',
    description: '',
  }, // 表单提交数据
})
// 选择的行
function selectTableChange(val: any) {
  selectList.value = val
}
// 点击添加
function handleAdd() {
  roleData.enableAddModal = true
  title.value = '添加'
  roleData.fid = ''
  // saveRoleWay.value = []
  Object.keys(roleData.form).forEach((key) => {
    roleData.form[key] = ''
  })
  rolePermsWay.value = []
  handleEditPerm({})
}
// 添加/修改
async function handleAddOk() {
  // roleData.form.password = this.md5(roleData.form.password);
  const auth = await formRef.value?.validate()
  if (!auth) {
    if (saveRoleWay.value.length === 0) {
      Message.warning('您还未分配菜单权限')
      return
    }
    // 给提交的form添加前缀处理
    const params = { ...roleData.form }
    
    let res
    if(!roleData.fid){
      res = await addRole(params)
    }else{
      res = await editRole(roleData.fid, params)
    }
    if (res.data.success) {
      Message.success(`${roleData.fid ? '修改' : '添加'}成功!`)
      roleData.enableAddModal = false
      tablePageRef.value.init()
    }
  }
}
// 点击修改地址
function handleEdit(val: any) {
  title.value = '编辑'
  if (val) {
    Object.keys(val.record).forEach((key) => {
      // eslint-disable-next-line no-prototype-builtins
      if (roleData.form.hasOwnProperty(key)){
        roleData.form[key] = val.record[key]
      }
    })
    roleData.fid = val.record.id
    roleData.enableAddModal = true
    handleEditPerm(val)
  }
}
// 回调删除
function handleDelete(data: any) {
  modal.confirm({
    title: '确认删除',
    content: `您确认要删除么?`,
    alignCenter: false,
    onOk: async () => {
      const res = await deleteRole(data.record.id)
      if (res.data.success) {
        Message.success('删除成功')
        tablePageRef.value.init()
      }
    },
  })
}
// 批量删除
function delAll() {
  if (selectList.value.length <= 0) {
    Message.error('您还未选择要删除的数据')
    return
  }
  selectList.value.forEach((item: any) => {
    ids.value += `${item.id},`
  })
  const joinid = ids.value.substring(0, ids.value.length - 1)
  modal.confirm({
    title: '确认删除',
    content: `您确认要删除所选的${selectList.value.length}条数据?`,
    alignCenter: false,
    onOk: async () => {
      const res = await deleteRole(joinid)
      if (res.data.success) {
        Message.success('删除成功')
        tablePageRef.value.init()
      }
    },
  })
}
// 判断角色拥有的权限节点勾选
function hasPerm(p: any, rolePerms: any) {
  if (!rolePerms)
    return false
  let flag = false
  for (let i = 0; i < rolePerms.length; i += 1) {
    if (p.id === rolePerms[i].menuId) {
      p.isSuper = rolePerms[i].isSuper
      flag = true
      break
    }
  }
  if (flag) {
    return true
  }
  return false
}
// 递归判断子节段
function checkPermTree(permData: any, rolePerms: any) {
  permData.forEach((p: any) => {
    if (hasPerm(p, rolePerms) && p.status !== -1) {
      if (p.children && p.children.length === 0) {
        p.checked = true
      }
    }
    else {
      p.checked = false
    }
    if (p.children && p.children.length > 0) {
      checkPermTree(p.children, rolePerms)
    }
  })
}
// 菜单权限
async function handleEditPerm(val: any) {
  // 点击菜单权限每次将赋值的isSuper数据给清空掉
  permData.value.forEach((item: any) => {
    if (item.children.length !== 0) {
      item.children.forEach((child: any) => {
        if (child.children.length !== 0) {
          child.children.forEach((kid: any) => {
            kid.key = kid.id
            delete kid.isSuper
          })
        }
        delete child.isSuper
      })
    }
    delete item.isSuper
  })
  title.value = `分配${val.record.name}的菜单权限`
  editRolePermId.value = val.record.id
  // 匹配勾选
  let rolePerms = []
  // 当前角色的菜单权限
  const res = await selectRoleMenu(val.record.id)
  if (res.data.result) {
    rolePerms = res.data.result
    rolePermsWay.value = res.data.result.map((item: any) => {
      return item.menuId
    })
  }
  // 递归判断子节点是否可以选中
  checkPermTree(permData.value, rolePerms)
  // permModalVisible.value = true;
}

// 分配菜单权限
function submitPermEdit() {
  if(!rolePermsWay.value.length){
    Message.error('请选择菜单权限')
    return
  }
  saveRoleWay.value = []
  selectIsSuperModel.value = true // 打开选择权限
  let selectedNodes = treeRef.value.getCheckedNodes()
  const harfNodes = treeRef.value.getHalfCheckedNodes()
  // 判断是否有半选中的节点
  if (harfNodes.length > 0) {
    selectedNodes = selectedNodes.concat(harfNodes)
  }
  const way = [] as any
  selectedNodes.forEach((e: any) => {
    const perm = {
      title: e.title,
      isSuper: e.isSuper ? (e.isSuper = true) : (e.isSuper = false),
      menuId: e.id,
      roleId: editRolePermId.value,
      level: e.level,
    }
    way.push(perm)
    saveRoleWay.value = way
  })
}
// 查询菜单
function getPermList() {
  getAllPermissionList({ version: 'v3', }).then((res) => {
    if (res.data.success) {
      permData.value = res.data.result.map((item: any) => {
        delete item.icon
        return item
      })
    }
  })
}
// 设置权限
function setRole(val: any) {
  let enable = false
  if (val === 'onlyView') {
    enable = false
  }
  else {
    enable = true
  }
  saveRoleWay.value.forEach((item: any) => {
    item.isSuper = enable
  })
}

// 保存权限
function saveRole() {
  saveRoleMenu(editRolePermId.value,saveRoleWay.value).then((res) => {
    if (res.data.success) {
      Message.success('操作成功')
      tablePageRef.value.init()
      permModalVisible.value = false
    }
  })
  // 筛选出已选中的权限id
  const superRoleIds = saveRoleWay.value
    .filter((item: any) => item.isSuper === true)
    .map((item: any) => item.menuId)
    // 替换原菜单数据
  permData.value.forEach((item: any) => {
    if (superRoleIds.includes(item.id)) {
      item.isSuper = true
    }
    else {
      if ((item.isSuper !== '' || item.isSuper !== undefined) && rolePermsWay.value.includes(item.id)) {
        item.isSuper = false
      }
    }
    if (item.children && item.children.length > 0) {
      item.children.forEach((child: any) => {
        if (superRoleIds.includes(child.id)) {
          child.isSuper = true
        }
        else {
          if ((child.isSuper !== '' || child.isSuper !== undefined) &&  rolePermsWay.value.includes(child.id)) {
            child.isSuper = false
          }
        }
        if (child.children && child.children.length > 0) {
          child.children.forEach((kid: any) => {
            if (superRoleIds.includes(kid.id)) {
              kid.isSuper = true
            }
            else {
              if ((kid.isSuper !== '' || kid.isSuper !== undefined) && rolePermsWay.value.includes(kid.id)) {
                kid.isSuper = false
              }
            }
          })
        }
      })
    }
  })
}
onMounted(() => {
  // 获取所有菜单权限树
  getPermList()
})
</script>

<template>
  <a-card class="general-card" title="角色权限" :bordered="false">
    <a-row style="margin-bottom: 16px">
      <a-col :span="16">
        <a-space>
          <a-button type="primary" @click="handleAdd">
            添加
          </a-button>
          <a-button @click="delAll">
            批量删除
          </a-button>
        </a-space>
      </a-col>
    </a-row>
    <PickTablePage
      ref="tablePageRef"
      :columns="columnsTable"
      :methods="sortMethods"
      :api="getRoleList"
      :checkbox="true"
      @delete="handleDelete"
      @editor="handleEdit"
      @edit-perm="handleEditPerm"
      @select-table-change="selectTableChange"
    >
      <template #btnList="{ data }">
        <a-space size="large">
          <a-switch
            v-model="data.disabled"
            checked-value="OPEN"
            unchecked-value="CLOSE"
          >
            <template #checked>
              启用
            </template>
            <template #unchecked>
              禁用
            </template>
          </a-switch>
        </a-space>
      </template>
    </PickTablePage>
    <!-- 添加/编辑modal -->
    <a-modal
      v-model:visible="roleData.enableAddModal"
      :align-center="false"
      :footer="false"
      :mask-closable="false"
    >
      <template #title>
        {{ title }}
      </template>
      <a-form ref="formRef" :model="roleData.form" @submit="handleAddOk">
        <a-form-item
          field="name"
          label="角色名称"
          :rules="[REQUIRED, VARCHAR20]"
          :validate-trigger="['change']"
        >
          <a-input v-model="roleData.form.name" />
        </a-form-item>
        <a-form-item field="code" label="备注" :validate-trigger="['change']">
          <a-input v-model="roleData.form.description" />
        </a-form-item>
        <a-form-item
          field="code"
          label="菜单权限"
          :validate-trigger="['change']"
        >
          <div w-full flex items-end justify-between>
            <a-tree
              ref="treeRef"
              v-model:checked-keys="rolePermsWay"
              :data="permData"
              :checkable="true"
              :multiple="true"
              :field-names="{ children: 'children', title: 'title', key: 'id' }"
              :only-check-leaf="true"
            >
              <template #extra="nodeData">
                <a-tag
                  v-if="nodeData.isSuper === true"
                  color="arcoblue"
                  style="margin-left: 10px"
                >
                  操作权限
                </a-tag>
                <a-tag
                  v-if="nodeData.isSuper === false"
                  color="green"
                  style="margin-left: 10px"
                >
                  查看权限
                </a-tag>
              </template>
            </a-tree>
            <div flex flex-col items-end>
              <a-button size="mini" type="primary" @click="submitPermEdit">
                编辑菜单权限
              </a-button>
              <span class="tips">编辑完权限保存后生效</span>
            </div>
          </div>
        </a-form-item>

        <a-form-item label="操作">
          <a-button
            :loading="roleData.formLoading"
            html-type="submit"
            type="primary"
          >
            保存
          </a-button>
        </a-form-item>
      </a-form>
    </a-modal>

    <a-modal
      v-model:visible="permModalVisible"
      :align-center="false"
      @cancel="permModalVisible = false"
      @ok="submitPermEdit"
    >
      <template #title>
        {{ title }}
      </template>
      <div>

        <a-tree
          ref="treeRef"
          v-model:checked-keys="rolePermsWay"
          :data="permData"
          :checkable="true"
          :multiple="true"
          :field-names="{ children: 'children', title: 'title', key: 'id' }"
          :only-check-leaf="true"
        >
          <template #extra="nodeData">
            <a-tag
              v-if="nodeData.isSuper === true"
              color="arcoblue"
              style="margin-left: 10px"
            >
              操作权限
            </a-tag>
            <a-tag
              v-if="nodeData.isSuper === false"
              color="green"
              style="margin-left: 10px"
            >
              查看权限
            </a-tag>
          </template>
        </a-tree>
      </div>
    </a-modal>

    <a-modal
      v-model:visible="selectIsSuperModel"
      :align-center="false"
      title="选择菜单权限"
      :width="800"
      @ok="saveRole"
    >
      <div class="btns">
        <a-button class="btn-item" type="outline" @click="setRole">
          一键选中·数据权限
        </a-button>
        <a-button class="btn-item" type="outline" @click="setRole('onlyView')">
          一键选中·查看权限
        </a-button>
      </div>
      <div class="role-list">
        <div
          v-for="(item, index) in saveRoleWay"
          :key="index"
          class="role-item"
        >
          <div class="title">
            {{ item.title }}
          </div>
          <div class="content">
            <a-radio-group
              v-model="item.isSuper"
              type="button"
              @change="changeIsSuper($event, item)"
            >
              <a-radio :value="true">
                操作数据权限
              </a-radio>
              <a-radio :value="false">
                查看权限
              </a-radio>
            </a-radio-group>
          </div>
        </div>
      </div>
    </a-modal>
  </a-card>
</template>

<style lang="less" scoped>
  .role-list {
  height: 500px;
  overflow-y: auto;
  display: flex;
  flex-wrap: wrap;
}
.role-item {
  width: 50%;
  display: flex;
  padding: 20px 0;
  align-items: center;
  > .title {
    flex: 2;
    text-align: right;
  }
  > .content {
    flex: 10;
  }
}

.btns {
  display: flex;
  align-items: center;
  justify-content: center;
}
.btn-item {
  margin-right: 20px;
}
.title {
  font-weight: bold;
  margin-right: 20px;
}

.tips {
  color: #999999;
  font-size: 12px;
  margin-top: 4px;
}
</style>
